// Copyright 2021 by 马万里. All rights reserved.
// 开发团队 ：   鸡中之霸
// 开发人员 ：   马万里
// 开发时间 ：   2021/3/2 21:17
// 文件名称 ：   order.go
// 工程名称 ：   seckill
// 开发工具 ：   GoLand
//

package repositories

import (
	"backend/common"
	"backend/datamodels"
	"database/sql"
)

type IOrderRepository interface {
	Conn() (err error)
	Insert(o *datamodels.Order) (id int64, err error)
	Delete(id int64) bool
	Update(o *datamodels.Order) (err error)
	SelectByKey(id int64) (o *datamodels.Order, err error)
	SelectAll() (ol []*datamodels.Order, err error)
	SelectAllWithInfo() (orderInfo map[int]map[string]string, err error)
}

type OrderManager struct {
	table     string
	mysqlConn *sql.DB
}

func NewOrderManager(table string, db *sql.DB) IOrderRepository {
	return &OrderManager{
		table:     table,
		mysqlConn: db,
	}
}

func (om *OrderManager) Conn() (err error) {
	if om.mysqlConn == nil {
		om.mysqlConn, err = common.NewMysqlConn()
		if err != nil {
			return err
		}
	}
	if om.table == "" {
		om.table = "order"
	}
	return
}

func (om *OrderManager) Insert(o *datamodels.Order) (id int64, err error) {
	if err = om.Conn(); err != nil {
		return
	}
	sqlStr := "INSERT order SET userID=?, productID=?, orderStatus=?"
	stmt, err := om.mysqlConn.Prepare(sqlStr)
	if err != nil {
		return
	}
	defer stmt.Close()
	result, err := stmt.Exec(o.UserId, o.ProductId, o.OrderStatus)
	if err != nil {
		return
	}
	return result.LastInsertId()
}

func (om *OrderManager) Delete(id int64) bool {
	if err := om.Conn(); err != nil {
		return false
	}
	sqlStr := "INSERT FROM order WHERE ID=?"
	stmt, err := om.mysqlConn.Prepare(sqlStr)
	if err != nil {
		return false
	}
	defer stmt.Close()
	_, err = stmt.Exec(id)
	if err != nil {
		return false
	}
	return true
}

func (om *OrderManager) Update(o *datamodels.Order) (err error) {
	if err = om.Conn(); err != nil {
		return err
	}
	sqlStr := "UPDATE order SET userID=?, productID=?, orderStatus=? WHERE ID=?"
	stmt, err := om.mysqlConn.Prepare(sqlStr)
	if err != nil {
		return err
	}
	_, err = stmt.Exec(o.UserId, o.ProductId, o.OrderStatus, o.ID)
	return err
}

func (om *OrderManager) SelectByKey(id int64) (o *datamodels.Order, err error) {
	if err = om.Conn(); err != nil {
		return &datamodels.Order{}, err
	}
	sqlStr := "SELECT * FROM order WHERE ID=?"
	stmt, err := om.mysqlConn.Prepare(sqlStr)
	if err != nil {
		return &datamodels.Order{}, err
	}
	row, err := stmt.Query(id)
	if err != nil {
		return &datamodels.Order{}, err
	}
	result := common.GetResultRow(row)
	if len(result) == 0 {
		return &datamodels.Order{}, err
	}
	o = new(datamodels.Order)
	common.DataToStructByTagSql(result, o)
	return
}

func (om *OrderManager) SelectAll() (ol []*datamodels.Order, err error) {
	if err = om.Conn(); err != nil {
		return nil, err
	}
	sqlStr := "SELECT * FROM order"
	stmt, err := om.mysqlConn.Prepare(sqlStr)
	if err != nil {
		return nil, err
	}
	rows, err := stmt.Query()
	if err != nil {
		return nil, err
	}
	resultRows := common.GetResultRows(rows)
	if len(resultRows) == 0 {
		return nil, err
	}
	for _, v := range resultRows {
		o := new(datamodels.Order)
		common.DataToStructByTagSql(v, o)
		ol = append(ol, o)
	}
	return
}

func (om *OrderManager) SelectAllWithInfo() (orderInfo map[int]map[string]string, err error) {
	if err = om.Conn(); err != nil {
		return nil, err
	}
	sqlStr := "SELECT o.ID, p.productName, o.orderStatus FROM order AS o LEFT JOIN product as p ON o.productID=p.ID"
	stmt, err := om.mysqlConn.Prepare(sqlStr)
	if err != nil {
		return nil, err
	}
	rows, err := stmt.Query()
	if err != nil {
		return nil, err
	}
	return common.GetResultRows(rows), err
}
